package com.springboot.springbootlogindemo.service.serviceImpl;

import cn.hutool.core.bean.BeanUtil;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.springboot.springbootlogindemo.DTO.SongListDTO;

import com.springboot.springbootlogindemo.domain.MusicCollection;
import com.springboot.springbootlogindemo.domain.Song;
import com.springboot.springbootlogindemo.domain.SongList;
import com.springboot.springbootlogindemo.domain.User;
import com.springboot.springbootlogindemo.mapper.MusicCollectionMapper;
import com.springboot.springbootlogindemo.mapper.SongListMapper;

import com.springboot.springbootlogindemo.mapper.SongMapper;
import com.springboot.springbootlogindemo.mapper.UserMapper;
import com.springboot.springbootlogindemo.service.SongListService;

import com.springboot.springbootlogindemo.utils.CacheClient;
import com.springboot.springbootlogindemo.utils.Result;
import com.springboot.springbootlogindemo.utils.UserHolder;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * 歌单service实现类
 */
@Service
public class SongListServiceImpl extends ServiceImpl<SongListMapper, SongList> implements SongListService {

    @Resource
    private SongListMapper songListMapper;

    @Resource
    private SongMapper songMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private CacheClient cacheClient;

    @Resource
    private MusicCollectionMapper musicCollectionMapper;

    /**
     * 实现添加歌单,这边就不添加进缓存了，添加之后要查看的话就会增加缓存的。
     *
     * @param songListDTO
     * @return
     */
    @Override
    public Result addSongList(SongListDTO songListDTO) {

        //搜索确保不重复
        SongList songList = songListMapper.selectOne(new QueryWrapper<SongList>().eq("title",songListDTO.getTitle()));

        if (songList != null) return Result.error("123", "歌单创建失败，歌单名重复");

        //DTO转实体类
        songList = BeanUtil.copyProperties(songListDTO, SongList.class);

        //设置属性
        songList.setUserId(UserHolder.getUser().getId());

        save(songList);

        return Result.success(songList, "歌单已添加");
    }


    /**
     * 实现修改歌单属性，这里需要保证数据一致性,为了保证一致性，这里需要用到事务，保证修改数据库和删除缓存是一个事务
     *
     * @param songListDTO
     * @return
     */
    @Override
    @Transactional//这个注解表示事务
    public Result updateSongList(SongListDTO songListDTO) {

        Long id = songListDTO.getId();
        SongList songList = songListMapper.selectById(id);
        if (songList == null) return Result.error("123", "歌单不存在");
        String pic = songListDTO.getPic();
        String title = songListDTO.getTitle();
        String introduction = songListDTO.getIntroduction();
        if (pic != null) {
            songList.setPic(pic);
        }
        if (title != null) {
            songList.setTitle(title);
        }
        if (introduction != null) {
            songList.setIntroduction(introduction);
        }

        save(songList);
        //修改数据库之后删除缓存
        stringRedisTemplate.delete("cache:songList:" + id);
        return Result.success("修改成功");
    }

    /**
     * 删除歌单，同上，保持数据一致性
     * @param songListId
     * @return
     */
    @Override
    @Transactional
    public Result deleteSongList(Long songListId) {

        SongList songList = getById(songListId);

        if (songList == null) return Result.error("123", "歌单不存在");

        songListMapper.deleteById(songListId);

        stringRedisTemplate.delete("cache:songList" + songListId);

        return Result.success("删除成功");
    }


    /**
     * 这边还不能实现，因为存到redis里面的是cache:hot:songList:id的key，然后普通的songList是cache:songList:id的key
     * 得等到实现点赞功能之后，然后创建任务调度线程池来周期性将热点歌单存到cache:hot:songList里面去，那时候才可以找到热点歌单。
     *
     *
     *这边明显是有问题的，这里是不需要有id的，应该直接展示热门歌单才对
     * @param id
     * @return
     */
    @Override
    public Result queryHotSongListById(Long id) {
        SongList songList = cacheClient.queryWithLogicalExpire("cache:hot:songList:", id, SongList.class,this::getById , 30L, TimeUnit.MINUTES);
        if (songList == null) {
            return Result.error("123", "歌单不存在");
        }
        return Result.success(songList);
    }


    /**
     * 用于查找歌单
     *这边写的还有问题，不应该是查找歌单的，应该是展示所有歌单，当然如果多调用几次也不是不可以
     * @param id
     * @return
     */
    @Override
    public Result querySongListById(Long id) {
        //这里还只是单纯的将歌单信息保存到redis，歌单里面的歌曲什么都没有保存进去

        SongList songList = cacheClient.<SongList,Long>queryWithPassThrough("cache:songList:", id, SongList.class,this::getById, 30L, TimeUnit.MINUTES);
        if (songList == null) {
            return Result.error("123", "歌单不存在");
        }
        return Result.success(songList);
    }





}
